package com.sylar.happyreader.view;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;

public class MyHorizontalScrollView extends HorizontalScrollView {

	private View btnView;

	public MyHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	public MyHorizontalScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public MyHorizontalScrollView(Context context) {
		super(context);
		init(context);
	}

	void init(Context context) {
		// remove the fading as the HSV looks better without it
		setHorizontalFadingEdgeEnabled(false);
		setVerticalFadingEdgeEnabled(false);
	}

	public void setShowMenuBtn(View btn) {
		this.btnView = btn;
		if (this.btnView != null) {
			this.btnView.setOnClickListener(new ClickListenerForScrolling(this));
		}
	}

	/**
	 * @param children
	 *            The child Views to add to parent.
	 * @param scrollToViewIdx
	 *            The index of the View to scroll to after initialisation.
	 * @param sizeCallback
	 *            A SizeCallback to interact with the HSV.
	 */
	public void initViews(View[] children, int scrollToViewIdx, SizeCallback sizeCallback) {
		// A ViewGroup MUST be the only child of the HSV
		ViewGroup parent = (ViewGroup) getChildAt(0);

		// Add all the children, but add them invisible so that the layouts are
		// calculated, but you can't see the Views
		for (int i = 0; i < children.length; i++) {
			if(i==1)
				children[i].setVisibility(View.VISIBLE);
			else
				children[i].setVisibility(View.GONE);
			parent.addView(children[i]);
		}

		OnGlobalLayoutListener listener = new MyOnGlobalLayoutListener(parent, children, scrollToViewIdx, sizeCallback);
		getViewTreeObserver().addOnGlobalLayoutListener(listener);
	}

	public boolean onTouchEvent(MotionEvent ev) {
		// Do not allow touch events.
		return false;
	}

	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// Do not allow touch events.
		return false;
	}

	/**
	 * An OnGlobalLayoutListener impl that passes on the call to onGlobalLayout
	 * to a SizeCallback, before removing all the Views in the HSV and adding
	 * them again with calculated widths and heights.
	 */
	class MyOnGlobalLayoutListener implements OnGlobalLayoutListener {
		ViewGroup parent;
		View[] children;
		int scrollToViewIdx;
		int scrollToViewPos = 0;
		SizeCallback sizeCallback;

		public MyOnGlobalLayoutListener(ViewGroup parent, View[] children, int scrollToViewIdx, SizeCallback sizeCallback) {
			this.parent = parent;
			this.children = children;
			this.scrollToViewIdx = scrollToViewIdx;
			this.sizeCallback = sizeCallback;
		}

		public void onGlobalLayout() {

			final HorizontalScrollView me = MyHorizontalScrollView.this;

			me.getViewTreeObserver().removeGlobalOnLayoutListener(this);

			if (sizeCallback != null)
				sizeCallback.onGlobalLayout();

			parent.removeViewsInLayout(0, children.length);

			final int w = me.getMeasuredWidth();
			final int h = me.getMeasuredHeight();
			int[] dims = new int[2];
			scrollToViewPos = 0;
			for (int i = 0; i < children.length; i++) {
				if (sizeCallback != null)
					sizeCallback.getViewSize(i, w, h, dims);
//				if(i==scrollToViewIdx)
//					children[i].setVisibility(View.VISIBLE);
//				else{
//					children[i].setVisibility(View.GONE);
//				}
				parent.addView(children[i], dims[0], dims[1]);
				if (i < scrollToViewIdx) {
					scrollToViewPos += dims[0];
				}
			}

			new Handler().post(new Runnable() {

				public void run() {
					me.scrollBy(scrollToViewPos, 0);
				}
			});
		}
	}

	public interface SizeCallback {
		public void onGlobalLayout();

		public void getViewSize(int idx, int w, int h, int[] dims);
	}

	public static class SizeCallbackForMenu implements SizeCallback {
		int btnWidth;
		View btnSlide;

		public SizeCallbackForMenu(View btnSlide) {
			super();
			this.btnSlide = btnSlide;
		}

		public void onGlobalLayout() {
			btnWidth = btnSlide.getWidth();
		}

		public void getViewSize(int idx, int w, int h, int[] dims) {
			dims[0] = w;
			dims[1] = h;
			final int menuIdx = 0;
			if (idx == menuIdx) {
				dims[0] = w - (w - w / 6);
			}

		}
	}

	public boolean canCloseMenu() {
		ViewGroup parent = (ViewGroup) getChildAt(0);
		View menu = parent.getChildAt(0);
		int menuWidth = menu.getWidth();
		if (menu.getVisibility() == View.VISIBLE) {
			menu.setVisibility(View.GONE);
			int left = menuWidth;
			this.smoothScrollTo(left, 0);
			return true;
		}
		return false;
	}
	
	public void showOrCloseMenu() {
		ViewGroup parent = (ViewGroup) getChildAt(0);
		View menu = parent.getChildAt(0);
		int menuWidth = menu.getWidth();
		if (menu.getVisibility() == View.VISIBLE) {
			menu.setVisibility(View.GONE);
			int left = menuWidth;
			this.smoothScrollTo(left, 0);
			
		}else{
			menu.setVisibility(View.VISIBLE);
			this.smoothScrollTo(0, 0);
		}
	}

	private boolean menuOut = false;

	public class ClickListenerForScrolling implements OnClickListener {
		HorizontalScrollView scrollView;
		View menu;

		public ClickListenerForScrolling(HorizontalScrollView scrollView) {
			super();
			this.scrollView = scrollView;
			ViewGroup parent = (ViewGroup) scrollView.getChildAt(0);
			this.menu = parent.getChildAt(0);
			
		}

		public void onClick(View v) {
			int menuWidth = menu.getWidth();
			if (menu.getVisibility()==View.GONE) {
				menu.setVisibility(View.VISIBLE);
				int left = 0;
				scrollView.smoothScrollTo(left, 0);
			} else {
				menu.setVisibility(View.GONE);
				int left = menuWidth;
				scrollView.smoothScrollTo(left, 0);
			}
			menuOut = !menuOut;
		}
	}

}
